#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Maven安装器GUI工具 - 修复版
功能：
1. 自动检测操作系统
2. 获取Maven版本列表
3. 提供GUI界面选择版本和安装目录
4. 自动下载和安装Maven
5. 支持深色/浅色主题
6. 安装历史记录
7. 解决macOS兼容性问题
"""

import platform
import requests
import os
import sys
import subprocess
import threading
import zipfile
import tarfile
from pathlib import Path
import shutil
import warnings
from datetime import datetime
import time

# 忽略SSL警告
warnings.filterwarnings('ignore', message='urllib3 v2 only supports OpenSSL 1.1.1+')

# 使用最新稳定的Maven版本
MAVEN_VERSION = "3.9.11"
MAVEN_DOWNLOAD_URL = f"https://dlcdn.apache.org/maven/maven-3/{MAVEN_VERSION}/binaries/apache-maven-{MAVEN_VERSION}-bin.tar.gz"
MAVEN_DOWNLOAD_URL_WIN = f"https://dlcdn.apache.org/maven/maven-3/{MAVEN_VERSION}/binaries/apache-maven-{MAVEN_VERSION}-bin.zip"

# 检查是否可以使用tkinter
try:
    import tkinter as tk
    from tkinter import ttk, messagebox, filedialog
    GUI_AVAILABLE = True
except Exception as e:
    print(f"无法加载GUI库: {str(e)}")
    print("将使用命令行界面替代")
    GUI_AVAILABLE = False

def detect_os():
    """检测操作系统信息"""
    system = platform.system().lower()
    machine = platform.machine().lower()
    
    os_info = {
        'system': system,
        'machine': machine,
        'platform': platform.platform(),
        'version': platform.version()
    }
    
    # 确定下载文件扩展名
    if system == 'windows':
        os_info['extension'] = 'zip'
        os_info['binary_name'] = 'mvn.cmd'
        os_info['download_url'] = MAVEN_DOWNLOAD_URL_WIN
    else:  # macOS/Linux
        os_info['extension'] = 'tar.gz'
        os_info['binary_name'] = 'mvn'
        os_info['download_url'] = MAVEN_DOWNLOAD_URL
    
    return os_info

def get_default_install_path(os_info):
    """获取默认安装路径（用户目录下，避免权限问题）"""
    home_dir = os.path.expanduser("~")
    
    if os_info['system'] == 'windows':
        return os.path.join(home_dir, 'Maven')
    else:  # macOS/Linux
        return os.path.join(home_dir, 'maven')

def download_file(url, filepath, progress_callback=None):
    """下载文件"""
    print(f"开始下载: {url}")
    response = requests.get(url, stream=True, timeout=30)
    response.raise_for_status()
    
    total_size = int(response.headers.get('content-length', 0))
    downloaded_size = 0
    start_time = time.time()
    
    with open(filepath, 'wb') as f:
        for chunk in response.iter_content(chunk_size=8192):
            f.write(chunk)
            downloaded_size += len(chunk)
            
            if total_size > 0:
                progress = (downloaded_size / total_size) * 100
                elapsed_time = time.time() - start_time
                
                if elapsed_time > 0:
                    speed = downloaded_size / elapsed_time / 1024  # KB/s
                    
                    # 如果提供了回调函数，调用它
                    if progress_callback:
                        progress_callback(progress, downloaded_size, total_size, speed)
                    else:
                        print(f"\r下载进度: {progress:.1f}% ({downloaded_size//1024//1024}MB/{total_size//1024//1024}MB) - {speed:.1f} KB/s", end='')
                else:
                    if progress_callback:
                        progress_callback(progress, downloaded_size, total_size, 0)
                    else:
                        print(f"\r下载进度: {progress:.1f}% ({downloaded_size//1024//1024}MB/{total_size//1024//1024}MB)", end='')
    
    print("\n下载完成!")

def extract_file(filepath, extract_dir):
    """解压文件"""
    print("开始解压...")
    if filepath.endswith('.zip'):
        with zipfile.ZipFile(filepath, 'r') as zip_ref:
            zip_ref.extractall(extract_dir)
    elif filepath.endswith('.tar.gz'):
        with tarfile.open(filepath, 'r:gz') as tar_ref:
            tar_ref.extractall(extract_dir)
    print("解压完成!")

def show_environment_setup_cli(maven_home, os_info):
    """显示环境变量配置信息（命令行版本）"""
    bin_path = os.path.join(maven_home, "bin")
    
    print("\nMaven安装完成!")
    print(f"\n安装路径: {maven_home}")
    print("\n请手动配置环境变量：")
    
    if os_info['system'] == 'windows':
        print(f"\nWindows:")
        print(f"set MAVEN_HOME={maven_home}")
        print(f"set PATH=%PATH%;{bin_path}")
    else:
        print(f"\nmacOS/Linux:")
        print(f"export MAVEN_HOME={maven_home}")
        print(f"export PATH=$PATH:{bin_path}")
        print(f"\n或者将以下内容添加到 ~/.bashrc 或 ~/.zshrc:")
        print(f"export MAVEN_HOME={maven_home}")
        print(f"export PATH=$PATH:{bin_path}")
    
    print("\n配置完成后，请重新打开终端并运行 'mvn --version' 验证安装。")

def install_maven_cli():
    """命令行版本的安装流程"""
    print("=== Maven安装器 (命令行版本) ===\n")
    
    # 检测操作系统
    os_info = detect_os()
    print(f"检测到操作系统: {os_info['platform']}")
    print(f"系统架构: {os_info['machine']}\n")
    
    # 使用固定版本
    selected_version = MAVEN_VERSION
    print(f"使用稳定版本: Maven {selected_version}")
    
    # 选择安装目录
    default_path = get_default_install_path(os_info)
    install_path = default_path
    try:
        user_path = input(f"请输入安装目录 (默认: {default_path}): ").strip()
        if user_path:
            install_path = user_path
    except:
        print(f"使用默认安装路径: {default_path}")
    
    print(f"安装目录: {install_path}")
    print()
    
    # 确认安装
    confirm = "y"  # 默认确认
    try:
        confirm = input("确认开始安装? (y/N): ").strip().lower()
    except:
        print("使用默认选择: y")
    
    if confirm in ['y', 'yes'] or not confirm:
        try:
            print(f"开始安装Maven {selected_version}")
            print(f"安装目录: {install_path}")
            
            # 创建安装目录
            os.makedirs(install_path, exist_ok=True)
            
            # 下载Maven
            download_url = os_info['download_url']
            print(f"下载URL: {download_url}")
            
            # 下载文件
            filename = f"apache-maven-{selected_version}-bin.{os_info['extension']}"
            filepath = os.path.join(install_path, filename)
            
            download_file(download_url, filepath)
            
            # 解压文件
            extract_file(filepath, install_path)
            
            # 移动文件到最终位置
            extracted_dir = os.path.join(install_path, f"apache-maven-{selected_version}")
            final_dir = os.path.join(install_path, "maven")
            
            if os.path.exists(final_dir):
                shutil.rmtree(final_dir)
            shutil.move(extracted_dir, final_dir)
            
            # 清理下载文件
            os.remove(filepath)
            
            print("Maven安装完成!")
            
            # 显示环境变量配置信息
            show_environment_setup_cli(final_dir, os_info)
            
        except Exception as e:
            print(f"安装失败: {str(e)}")
    else:
        print("安装已取消")

# 如果GUI可用，定义GUI类
if GUI_AVAILABLE:
    class MavenInstallerGUI:
        def __init__(self, root):
            self.root = root
            self.root.title("Maven安装器")
            self.root.geometry("650x600")
            self.root.resizable(True, True)
            
            # 设置样式
            self.style = ttk.Style()
            self.style.theme_use('clam')
            
            # 变量
            self.os_info = detect_os()
            self.selected_version = tk.StringVar(value=MAVEN_VERSION)
            self.install_path = tk.StringVar()
            self.download_progress = tk.DoubleVar()
            self.dark_mode = tk.BooleanVar(value=False)
            
            # 历史记录
            self.history_file = os.path.join(os.path.expanduser("~"), ".maven_installer_history.json")
            self.installation_history = []
            
            # 设置界面
            self.setup_ui()
            self.apply_theme()
        
        def setup_ui(self):
            """设置用户界面"""
            # 主框架
            main_frame = ttk.Frame(self.root, padding="10")
            main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
            
            # 配置网格权重
            self.root.columnconfigure(0, weight=1)
            self.root.rowconfigure(0, weight=1)
            main_frame.columnconfigure(0, weight=1)
            
            # 创建标签页
            notebook = ttk.Notebook(main_frame)
            notebook.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
            main_frame.rowconfigure(0, weight=1)
            
            # 安装页面
            install_frame = ttk.Frame(notebook, padding="10")
            notebook.add(install_frame, text="安装Maven")
            
            # 设置页面
            settings_frame = ttk.Frame(notebook, padding="10")
            notebook.add(settings_frame, text="设置")
            
            # 设置各个页面
            self.setup_install_page(install_frame)
            self.setup_settings_page(settings_frame)
        
        def setup_install_page(self, parent):
            """设置安装页面"""
            # 操作系统信息
            os_frame = ttk.LabelFrame(parent, text="操作系统信息", padding="10")
            os_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
            os_frame.columnconfigure(1, weight=1)
            
            ttk.Label(os_frame, text="操作系统:").grid(row=0, column=0, sticky=tk.W, padx=(0, 10))
            ttk.Label(os_frame, text=self.os_info['platform']).grid(row=0, column=1, sticky=tk.W)
            
            ttk.Label(os_frame, text="架构:").grid(row=1, column=0, sticky=tk.W, padx=(0, 10))
            ttk.Label(os_frame, text=self.os_info['machine']).grid(row=1, column=1, sticky=tk.W)
            
            # Maven版本
            version_frame = ttk.LabelFrame(parent, text="Maven版本", padding="10")
            version_frame.grid(row=1, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
            version_frame.columnconfigure(1, weight=1)
            
            ttk.Label(version_frame, text="版本:").grid(row=0, column=0, sticky=tk.W, padx=(0, 10))
            ttk.Label(version_frame, text=MAVEN_VERSION).grid(row=0, column=1, sticky=tk.W)
            
            # 安装目录选择
            install_frame = ttk.LabelFrame(parent, text="安装目录", padding="10")
            install_frame.grid(row=2, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
            install_frame.columnconfigure(1, weight=1)
            
            ttk.Label(install_frame, text="安装路径:").grid(row=0, column=0, sticky=tk.W, padx=(0, 10))
            install_entry = ttk.Entry(install_frame, textvariable=self.install_path)
            install_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(0, 10))
            
            browse_btn = ttk.Button(install_frame, text="浏览", command=self.browse_directory)
            browse_btn.grid(row=0, column=2)
            
            # 设置默认安装路径
            default_path = get_default_install_path(self.os_info)
            self.install_path.set(default_path)
            
            # 进度条
            progress_frame = ttk.LabelFrame(parent, text="安装进度", padding="10")
            progress_frame.grid(row=3, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
            progress_frame.columnconfigure(0, weight=1)
            
            self.progress_bar = ttk.Progressbar(progress_frame, variable=self.download_progress, maximum=100)
            self.progress_bar.grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 10))
            
            self.progress_label = ttk.Label(progress_frame, text="准备就绪")
            self.progress_label.grid(row=0, column=1)
            
            # 日志区域
            log_frame = ttk.LabelFrame(parent, text="安装日志", padding="10")
            log_frame.grid(row=4, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
            log_frame.columnconfigure(0, weight=1)
            log_frame.rowconfigure(0, weight=1)
            parent.rowconfigure(4, weight=1)
            
            self.log_text = tk.Text(log_frame, height=8, wrap=tk.WORD)
            scrollbar = ttk.Scrollbar(log_frame, orient=tk.VERTICAL, command=self.log_text.yview)
            self.log_text.configure(yscrollcommand=scrollbar.set)
            
            self.log_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
            scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
            
            # 按钮
            button_frame = ttk.Frame(parent)
            button_frame.grid(row=5, column=0, pady=(10, 0))
            
            self.install_btn = ttk.Button(button_frame, text="开始安装", command=self.start_installation)
            self.install_btn.pack(side=tk.LEFT, padx=(0, 10))
            
            self.cancel_btn = ttk.Button(button_frame, text="取消", command=self.cancel_installation, state="disabled")
            self.cancel_btn.pack(side=tk.LEFT)
            
            # 安装状态
            self.installing = False
        
        def setup_settings_page(self, parent):
            """设置设置页面"""
            # 主题设置
            theme_frame = ttk.LabelFrame(parent, text="主题设置", padding="10")
            theme_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
            
            theme_switch = ttk.Checkbutton(theme_frame, text="深色模式", variable=self.dark_mode,
                                        command=self.apply_theme)
            theme_switch.grid(row=0, column=0, sticky=tk.W)
            
            # 关于信息
            about_frame = ttk.LabelFrame(parent, text="关于", padding="10")
            about_frame.grid(row=1, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
            about_frame.columnconfigure(0, weight=1)
            
            about_text = """Maven安装器

版本: 1.0.0
作者: AI助手
描述: 一个用于自动安装Maven的图形界面工具

功能:
- 自动检测操作系统
- 自动下载和安装Maven
- 安装历史记录
- 主题切换
"""
            
            about_label = ttk.Label(about_frame, text=about_text, justify=tk.LEFT)
            about_label.grid(row=0, column=0, sticky=tk.W)
            
            parent.columnconfigure(0, weight=1)
        
        def apply_theme(self):
            """应用主题"""
            if self.dark_mode.get():
                # 深色主题
                self.style.configure('TFrame', background='#2c3e50')
                self.style.configure('TLabel', background='#2c3e50', foreground='#ecf0f1')
                self.style.configure('TLabelframe', background='#2c3e50', foreground='#ecf0f1')
                self.style.configure('TLabelframe.Label', background='#2c3e50', foreground='#ecf0f1')
                self.style.configure('TButton', background='#3498db', foreground='#ecf0f1')
                self.style.configure('TCheckbutton', background='#2c3e50', foreground='#ecf0f1')
                self.style.configure('TCombobox', background='#34495e', foreground='#ecf0f1')
                self.style.configure('TEntry', background='#34495e', foreground='#ecf0f1')
                self.style.configure('TProgressbar', background='#3498db')
                
                self.log_text.config(bg='#34495e', fg='#ecf0f1')
                self.root.configure(bg='#2c3e50')
            else:
                # 浅色主题
                self.style.theme_use('clam')
                self.log_text.config(bg='white', fg='black')
                self.root.configure(bg=self.style.lookup('TFrame', 'background'))
        
        def browse_directory(self):
            """浏览选择安装目录"""
            directory = filedialog.askdirectory(title="选择Maven安装目录")
            if directory:
                self.install_path.set(directory)
        
        def log_message(self, message):
            """添加日志消息"""
            timestamp = datetime.now().strftime('%H:%M:%S')
            self.log_text.insert(tk.END, f"[{timestamp}] {message}\n")
            self.log_text.see(tk.END)
            self.root.update_idletasks()
        
        def update_progress(self, progress, downloaded, total, speed):
            """更新进度条和标签"""
            self.download_progress.set(progress)
            self.progress_label.config(text=f"下载中... {downloaded//1024//1024}MB/{total//1024//1024}MB ({speed:.1f} KB/s)")
            self.root.update_idletasks()
        
        def start_installation(self):
            """开始安装"""
            if not self.install_path.get():
                messagebox.showerror("错误", "请选择安装目录")
                return
            
            # 确认安装
            result = messagebox.askyesno(
                "确认安装",
                f"确定要安装Maven {MAVEN_VERSION} 到 {self.install_path.get()} 吗？"
            )
            
            if result:
                self.installing = True
                self.install_btn.config(state="disabled")
                self.cancel_btn.config(state="normal")
                
                # 在后台线程中执行安装
                threading.Thread(target=self.install_maven, daemon=True).start()
        
        def cancel_installation(self):
            """取消安装"""
            self.installing = False
            self.install_btn.config(state="normal")
            self.cancel_btn.config(state="disabled")
            self.log_message("安装已取消")
        
        def install_maven(self):
            """安装Maven"""
            try:
                install_dir = self.install_path.get()
                
                self.log_message(f"开始安装Maven {MAVEN_VERSION}")
                self.progress_label.config(text="准备下载...")
                
                # 创建安装目录
                os.makedirs(install_dir, exist_ok=True)
                
                # 下载Maven
                download_url = self.os_info['download_url']
                self.log_message(f"下载URL: {download_url}")
                
                # 下载文件
                filename = f"apache-maven-{MAVEN_VERSION}-bin.{self.os_info['extension']}"
                filepath = os.path.join(install_dir, filename)
                
                # 使用带进度更新的下载函数
                def update_progress_wrapper(progress, downloaded, total, speed):
                    if not self.installing:
                        return
                    self.root.after(0, lambda: self.update_progress(progress, downloaded, total, speed))
                
                download_file(download_url, filepath, update_progress_wrapper)
                
                if not self.installing:
                    return
                
                self.log_message("下载完成，开始解压...")
                self.progress_label.config(text="正在解压...")
                
                # 解压文件
                extract_file(filepath, install_dir)
                
                if not self.installing:
                    return
                
                # 移动文件到最终位置
                extracted_dir = os.path.join(install_dir, f"apache-maven-{MAVEN_VERSION}")
                final_dir = os.path.join(install_dir, "maven")
                
                if os.path.exists(final_dir):
                    shutil.rmtree(final_dir)
                shutil.move(extracted_dir, final_dir)
                
                # 清理下载文件
                os.remove(filepath)
                
                self.log_message("Maven安装完成！")
                self.progress_label.config(text="安装完成")
                self.download_progress.set(100)
                
                # 显示环境变量配置信息
                self.show_environment_setup(final_dir)
                
            except Exception as e:
                self.log_message(f"安装失败: {str(e)}")
                self.progress_label.config(text="安装失败")
            finally:
                self.installing = False
                self.install_btn.config(state="normal")
                self.cancel_btn.config(state="disabled")
        
        def show_environment_setup(self, maven_home):
            """显示环境变量配置信息"""
            bin_path = os.path.join(maven_home, "bin")
            
            env_info = f"""
Maven安装完成！

安装路径: {maven_home}

请手动配置环境变量：

Windows:
set MAVEN_HOME={maven_home}
set PATH=%PATH%;{bin_path}

macOS/Linux:
export MAVEN_HOME={maven_home}
export PATH=$PATH:{bin_path}

或者将以下内容添加到 ~/.bashrc 或 ~/.zshrc:
export MAVEN_HOME={maven_home}
export PATH=$PATH:{bin_path}

配置完成后，请重新打开终端并运行 'mvn --version' 验证安装。
"""
            
            # 创建新窗口显示环境变量信息
            env_window = tk.Toplevel(self.root)
            env_window.title("环境变量配置")
            env_window.geometry("600x400")
            
            text_widget = tk.Text(env_window, wrap=tk.WORD, padx=10, pady=10)
            text_widget.pack(fill=tk.BOTH, expand=True)
            text_widget.insert(tk.END, env_info)
            text_widget.config(state=tk.DISABLED)
            
            # 添加复制按钮
            copy_btn = ttk.Button(env_window, text="复制到剪贴板", 
                                command=lambda: self.copy_to_clipboard(env_info))
            copy_btn.pack(pady=10)
        
        def copy_to_clipboard(self, text):
            """复制文本到剪贴板"""
            self.root.clipboard_clear()
            self.root.clipboard_append(text)
            messagebox.showinfo("成功", "环境变量配置信息已复制到剪贴板")

def main():
    # 尝试使用GUI，如果失败则使用命令行
    if GUI_AVAILABLE:
        try:
            root = tk.Tk()
            app = MavenInstallerGUI(root)
            root.mainloop()
        except Exception as e:
            print(f"GUI启动失败: {str(e)}")
            print("切换到命令行模式")
            install_maven_cli()
    else:
        install_maven_cli()

if __name__ == "__main__":
    main()
